import { v4 as uuidv4 } from 'uuid'
import { reactive, computed } from 'vue'
import {
  type AIAgent,
  type ChatMessage,
  AIGCStatus,
  MessageType,
  type MessageContent,
  MessageContentType,
  type IMessageParser
} from './interface'
import { AIGCSession } from './aigc-session'

import { IFlyParser } from './ifly-parser'
import { getMessageHistory } from '@/utils/api'

import { parseMarkdownToHTML } from './markdown-parser'
import { escapeHTML, processContent } from './lib'

export class ChatSession {
  public readonly conversionId?: string
  public readonly agentInfo: AIAgent
  public readonly isLocal: boolean = false
  public aicgSession: AIGCSession | undefined = undefined //当前生成对话信息

  private _messageListFromServer: ChatMessage[] = [] //本次会话开始时 线上历史消息
  private _aigcHistoryMessage: ChatMessage[] = [] //本次会话产生的历史消息
  private _welcomeMessage: ChatMessage[] = [] //欢迎消息

  private messageParser: IMessageParser = new IFlyParser()

  conversionName?: string
  createTime?: string

  private state = reactive({
    _messageListFromServer: this._messageListFromServer,
    _welcomeMessage: this._welcomeMessage,
    _aigcHistoryMessage: this._aigcHistoryMessage
  })

  public historyMessageList: ChatMessage[] = computed(() => {
    const target = [
      ...this.state._welcomeMessage,
      ...this.state._messageListFromServer,
      ...this.state._aigcHistoryMessage
    ]
    // console.log('historyMessageList Computed', target)
    return target
  })

  //发送按钮是否可用
  public canSend = computed(() => {
    //正在回答时不可发送，TODO token使用完，不可发送
    return !(
      this.aicgSession?.status === AIGCStatus.Started ||
      this.aicgSession?.status === AIGCStatus.InProgress
    )
  })

  //是否可添加附件
  public canAddAttend = computed(() => true)

  constructor(agentInfo: AIAgent, conversionId: string = '', isLocal: boolean = false) {
    this.conversionId = conversionId
    this.isLocal = this.conversionId ? false : true
    this.agentInfo = agentInfo

    // 准备欢迎消息
    if (agentInfo) {
      if (this.isLocal) {
        //本地新启会话 才显示欢迎消息
        const msgContent: MessageContent = {
          content: parseMarkdownToHTML(
            processContent(agentInfo.prologue || `欢迎使用 ${this.agentInfo.name}`)
          ),
          contentType: MessageContentType.Text,
          rowData: {}
        }
        const welcomeMessage: ChatMessage = {
          messageId: uuidv4(),
          contentList: [msgContent],
          messageType: MessageType.Text,
          isSend: false
        }
        this.state._welcomeMessage = [welcomeMessage]
      } else {
        //非本地会话，从服务器获取历史消息
        this.getMessageHistory()
      }
    }
    this.initAICGSession()
  }

  public async getMessageHistory(param?: any): Promise<ChatMessage[]> {
    try {
      const payload = { ...param }
      payload.session_id = this.conversionId
      const data = await getMessageHistory(payload)
      const messages = this.messageParser.messageListFromHistoryMessageResp(data)
      this.state._messageListFromServer = messages
      return data
    } catch (error) {
      console.error('获取消息历史时出错:', error)
      throw error
    }
  }

  public sendMessage(quesition: any): boolean {
    if (
      this.aicgSession &&
      (this.aicgSession.status === AIGCStatus.InProgress ||
        this.aicgSession.status === AIGCStatus.Started)
    ) {
      return false
    }

    this.aicgSession?.ask(quesition)

    return true
  }

  public reAsk(): boolean {
    if (!this.aicgSession) {
      this.aicgSession!.reAsk()
      return true
    }
    return false
  }

  initAICGSession(): void {
    this.aicgSession = new AIGCSession(
      this.agentInfo,
      this.isLocal ? '' : this.conversionId || '',
      this.isLocal,
      this,
      this.updateAIGCHistoryMessageCallBack
    )
  }
  //callback
  updateAIGCHistoryMessageCallBack(self: any, aigcMessageList: ChatMessage[]) {
    const copyList = [...self.state._aigcHistoryMessage]
    self.state._aigcHistoryMessage = copyList.concat(aigcMessageList)
  }
}
